#include "triangle.h"
#include <GL/gl.h>
#include <cmath>
//#include "utils.h"
#include "plane.h"

Triangle::Triangle(Point *p1, Point *p2, Point *p3)
{
    vertices_.push_back(p1);
    vertices_.push_back(p2);
    vertices_.push_back(p3);

    material_.set_ambient(CgColor(0.24725, 0.1995, 0.0745));
    material_.set_diffuse(CgColor(0.75164, 0.60648, 0.22648));
//    material_.set_specular(CgColor(0.628281, 0.555802, 0.366065));
    material_.set_specular(CgColor(1.0, 1.0, 1.0));
}

bool Triangle::intersect(const Ray &r, double &t, Vector &normal) const
{
    Plane plane(*vertices_[0], *vertices_[1], *vertices_[2]);
    double denominator = plane.normal() * r.dir();
//    if( compare_equals(denominator, 0.0) )
        return false;

    t = -plane.d() / denominator;
//    if( !compare_equals(t, 0.0) ) {
//        const Vector edge1 = *(vertices_[1]) - *(vertices_[0]);
//        const Vector edge2 = *(vertices_[2]) - *(vertices_[1]);
//        const Vector edge3 = *(vertices_[0]) - *(vertices_[2]);
//        const Point intersection_point = r.source() + t*r.dir();
//
//        return  (vecprod(edge1, intersection_point - *(vertices_[0]))*normal >= 0) &&
//                (vecprod(edge2, intersection_point - *(vertices_[1]))*normal >= 0) &&
//                (vecprod(edge3, intersection_point - *(vertices_[2]))*normal >= 0);
//    }

    return false;
}

void Triangle::openGlRender() const
{
    GLfloat gl_ambient[] = {material_.ambient().r(), material_.ambient().g(), material_.ambient().b(), 1.0};
    GLfloat gl_diffuse[] = {material_.diffuse().r(), material_.diffuse().g(), material_.diffuse().b(), 1.0};
    GLfloat gl_specular[] = {material_.specular().r(), material_.specular().g(), material_.specular().b(), 1.0};
    GLfloat shininess[] = {50.0f};
    Vector normal = vecprod(*vertices_[1] - *vertices_[0], *vertices_[2] - *vertices_[0]);
    normal.normalize();

    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, gl_ambient);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, gl_diffuse);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gl_specular);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
    glBegin(GL_TRIANGLES);
        glNormal3d(normal(0), normal(1), normal(2));
        glVertex3dv(vertices_[0]->toCArray());
        glVertex3dv(vertices_[1]->toCArray());
        glVertex3dv(vertices_[2]->toCArray());
    glEnd();
}

ICgObject* Triangle::clone() const
{
    Triangle *t = new Triangle(new Point(*vertices_[0]), new Point(*vertices_[1]), new Point(*vertices_[2]));
    t->multiplyCurrentTransformation(this->transformation_);
    t->material_ = this->material_;
    return t;
}
